<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>is挂载组件</title>
</head>
<body>

<div id="app">
    <table>
        <!-- 组件必须使用这种才能进入<table>内 -->
        <tbody is="my-component"> <!-- 这种方式最终渲染为
        <div id="app"><table><div>这里是全局注册的组件！</div></table></div>
        -->
        </tbody>


        <tbody>
        <my-component></my-component>   <!-- 这种方式最终渲染为
            <div id="app"><div>这里是全局注册的组件！</div><table><tbody></tbody></table></div>   -->
        </tbody>
    </table>
</div>

<hr>

<div id="app1">
    <my-component></my-component>
</div>

<hr>


<!-- 组件使用了3次，但是单击任意一个<button>，其余两个的数字也会加1，原因在于组件的data引用的是外部的数据out_data。 -->
<div id="app2">
    <yinyong-component></yinyong-component>
    <yinyong-component></yinyong-component>
    <yinyong-component></yinyong-component>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
    /**
     * Vue组件的模板在某些情况下会受到HTML的限制，如<table>内规定只允许使用<tr>、<td>、<th>等这些表格元素，因此在<table>内直接使用组件是无效的。
     * 常见的限制元素还有<ul>、<ol>、<select>。这时候需要使用特殊的is属性来进行组件的挂载！
     *
     *
     * 当然如果使用的是字符串模板，那是不受限制的，如后面介绍的.vue单文件用法。
     **/

    Vue.component("my-component", {
        template: "<div>这里是全局注册的组件！</div>"
    });

    var app = new Vue({
        el: "#app",
    });

    /**
     * 除了template选项外，组件中还可以像Vue实例那样使用其他的选项，如data、computed、methods等。
     * 但是在使用data时，和实例有一些区别，data必须是函数，且将数据return回去，这一点要格外注意。(说的是作为选项对象，不是作为Vue实例参数时)
     * （其实就是在子组件中需要注意data后面必须接一个函数且return回去）因为子组件通常是要被多次使用的，这样操作可以避免多个组件共享一个变量，造成问题
     * */
    Vue.component('my-component', {
        template: "<div>{{ message }}</div>",
        data: function () {
            return {
                message: "data作为选项对象时，后面必须接一个函数，且将函数进行返回"
            }
        },
    });

    var app1 = new Vue({
        el: "#app1",
    });


    /**
     * JavaScript对象是引用关系，所以如果return出的对象引用了外部的一个对象，那这个对象是共享的，任何一方的修改都会同步。
     * **/
    var out_data = {
        counter: 0
    };

    Vue.component('yinyong-component', {
        template: "<button @click='counter++'>{{counter}}</button>",
        data: function () {
            // return out_data;  //这里返回的是外部定义的数据out_data

            return {
                counter:0   //这里就不使用外部定义的数据，而是独立的对象counter
            }
        }
    });

    var app2 = new Vue({
        el: "#app2",
    })
</script>
</body>
</html>